<?php

namespace app\common\service;

use app\common\service\word\WordUtilsService;
use think\exception\ValidateException;

class TTLService extends ApiService
{
    private $vocalType;
    private $vocalType2;
    private const SUPPORTED_VOCAL_TYPES = ['youdao', 'tencent', 'doubao'];

    public function __construct()
    {
        $this->vocalType = env('TTL.VOCAL_TYPE_1', '');
        if (!in_array($this->vocalType, self::SUPPORTED_VOCAL_TYPES)) {
            throw new ValidateException('语音合成第三方配置错误');
        }

        $this->vocalType2 = env('TTL.VOCAL_TYPE_2', '');
        if (!empty($this->vocalType2) && !in_array($this->vocalType2, self::SUPPORTED_VOCAL_TYPES)) {
            throw new ValidateException('备用语音合成第三方配置错误');
        }
    }

    public function getEnVocalToUrl(string $text)
    {
        // 添加文本验证
        if (empty($text)) {
            $this->setError('文本不能为空');
            return false;
        }

        $bytes = $this->getEnVocalToByte($text, $this->vocalType);
        if (!$bytes) {
            $this->setError('获取语音失败');
            return false;
        }
        return $this->upload($text, $bytes);
    }


    public function upload($text, $bytes)
    {

        try {
            $ossSavePath = WordUtilsService::getVocalOssKey($text, 'mp3');
            $uploadService = new UploadService();
            $res = $uploadService->uploadFileSimple($bytes, $ossSavePath);
            if (!$res) {
                throw new ValidateException('上传失败');
            }
            return $res;
        } catch (\Exception|ValidateException $e) {
            $this->setError($e->getMessage());
            return false;
        }
    }

    public function getEnVocalToByte(string $text)
    {
        return $this->getEnVocalToByteConfig($text, $this->vocalType);
    }

    private function getEnVocalToByteConfig(string $text, string $vocalType)
    {

        try {
            switch ($vocalType) {
                case 'youdao':
                    $youdaoWordService = new YoudaoVocalService();
                    $bytes = $youdaoWordService->getEnVocalToByte($text);
                    if ($bytes) {
                        return $bytes;
                    }
                    // 只有当备用类型不同时才尝试
                    if ($this->vocalType2 && $vocalType !== $this->vocalType2) {
                        logSave([
                            "file" => __FILE__,
                            'message' => "语音合成失败，尝试使用备用方案 {$this->vocalType2}",
                        ], 'getEnVocalToByte');
                        return $this->getEnVocalToByteConfig($text, $this->vocalType2);
                    }
                    return false;

                case 'tencent':
                    $tencentWordService = new TencentVocalService();
                    return $tencentWordService->textToVoiceByte($text);
                case 'doubao':
                    $doubaoWordService = new DouBaoVocalService();
                    return $doubaoWordService->llmTts($text, 1.0);
            }
            return false;
        } catch (\Exception $e) {
            logSave([
                "file" => __FILE__,
                'message' => "语音合成异常: " . $e->getMessage(),
                'vocal_type' => $vocalType,
                'text' => $text
            ], 'getEnVocalToByte');
            return false;
        }
    }


    public function getSyllableVocalToUrl(string $text)
    {
        // 添加文本验证
        if (empty($text)) {
            $this->setError('文本不能为空');
            return false;
        }
        $bytes = $this->getSyllableVocalToByte($text);
        if (!$bytes) {
            $this->setError($this->getError());
            return false;
        }


        try {
            $ossSavePath = WordUtilsService::getVocalOssKey($text, 'mp3');
            $uploadService = new UploadService();
            $res = $uploadService->uploadFileSimple($bytes, $ossSavePath);

            if (!$res) {
                throw new ValidateException('上传失败');
            }
            return $res;
        } catch (\Exception|ValidateException $e) {
            $this->setError($e->getMessage());
            return false;
        }
    }

    public function getSyllableVocalToByte($text)
    {
        $youdaoVocalService = new YoudaoVocalService();
        $bytes = $youdaoVocalService->getTTSapiDictByte($text, 'youxiaoguan');
        if (!$bytes) {
            $this->setError('获取语音失败');
            return false;
        }
        return $bytes;
    }
}
